home *** CD-ROM | disk | FTP | other *** search
/ Mission 3 / Mission 3.zip / Mission 3.iso / texte / qed / src / event.c < prev    next >
C/C++ Source or Header  |  1998-10-29  |  13KB  |  601 lines

  1. #include "global.h"
  2. #include "aktion.h"
  3. #include "av.h"
  4. #include "clipbrd.h"
  5. #include "dd.h"
  6. #include "edit.h"
  7. #include "file.h"
  8. #include "find.h"
  9. #include "icon.h"
  10. #include "menu.h"
  11. #include "makro.h"
  12. #include "olga.h"
  13. #include "options.h"
  14. #include "projekt.h"
  15. #include "rsc.h"
  16. #include "se.h"
  17. #include "set.h"
  18. #include "string.h"
  19. #include "text.h"
  20. #include "window.h"
  21. #include "event.h"
  22.  
  23. bool    abort_prog = FALSE;        /* Falls TRUE -> sofort Ende */
  24.  
  25. /****** DEFINES **************************************************************/
  26.  
  27. #ifndef WM_SHADED
  28. #define WM_SHADED            0x5758
  29. #define WM_UNSHADED        0x5759
  30. #endif
  31.  
  32. #ifndef WM_M_BDROPPED
  33. #define WM_M_BDROPPED    100
  34. #endif
  35.  
  36. #ifndef DHST_ACK 
  37. #define DHST_ACK            0xDADE
  38. #endif
  39.  
  40. #ifndef FONT_CHANGED
  41. #define FONT_CHANGED     0x7A18
  42. #endif
  43.  
  44. #define MAX_EVENT         20
  45.  
  46. /****** TYPES ****************************************************************/
  47.  
  48. typedef struct
  49. {
  50.     int    which;
  51.     int    msg[8];
  52.     int    m_x;
  53.     int    m_y;
  54.     int    bstate;
  55.     int    kstate;
  56.     int    kreturn;
  57.     int    breturn;
  58. } EVENT;
  59.  
  60. /****** VARIABLES ************************************************************/
  61.  
  62. static EVENT    msg_queue[MAX_EVENT];
  63. static int        msg_head = 0,
  64.                     msg_tail = 0;
  65. static int        old_mx = 0,
  66.                     old_my = 0;     /* Immer die letzte Mausposition */
  67. static bool        menu_ctrl;
  68.  
  69. /****** FUNCTIONS ************************************************************/
  70.  
  71. static void handle_keybd    (int kstate, int kreturn);
  72. static void handle_button    (int m_x, int m_y, int bstate, int kstate, int breturn);
  73.  
  74. /*****************************************************************************/
  75.  
  76. static bool is_event(void)
  77. {
  78.     return (msg_head != msg_tail);
  79. }
  80.  
  81. static bool full_event(void)
  82. {
  83.     int next;
  84.  
  85.     next = msg_head+1;
  86.     if (next == MAX_EVENT)
  87.         next = 0;
  88.     return(next == msg_tail);
  89. }
  90.  
  91. static void add_event(EVENT *event)
  92. {
  93.     int next;
  94.  
  95.     if (event->which == MU_KEYBD && is_event())        /* Tastatur-Repeat? */
  96.     {
  97.         EVENT    *ptr = &msg_queue[msg_tail];
  98.  
  99.         if (ptr->which == MU_KEYBD && ptr->kreturn == event->kreturn &&
  100.             ptr->kstate == event->kstate)
  101.             return;
  102.     }
  103.  
  104.     next = msg_head + 1;
  105.     if (next == MAX_EVENT)
  106.         next = 0;
  107.     if (next == msg_tail)
  108.     {
  109.         inote(1, 0, FATALERR, 10);
  110.         return;
  111.     }
  112.     msg_queue[msg_head] = *event;
  113.     msg_head = next;
  114. }
  115.  
  116. static bool get_event(EVENT *event)
  117. {
  118.     if (msg_head != msg_tail)
  119.     {
  120.         *event = msg_queue[msg_tail];
  121.         msg_tail++;
  122.         if (msg_tail == MAX_EVENT) 
  123.             msg_tail = 0;
  124.         return TRUE;
  125.     }
  126.     return FALSE;
  127. }
  128.  
  129. static bool idle(void)
  130. {
  131.     EVENT ev;
  132.     int    events;
  133.  
  134.     if (full_event())
  135.         return FALSE;
  136.  
  137.     events = MU_KEYBD | MU_BUTTON | MU_MESAG | MU_TIMER;
  138.     if (mouse_sleeps())
  139.         events |= MU_M1;
  140.     ev.which = evnt_multi(events,    0x102, 3, 0,
  141.                                     1, old_mx, old_my, 1, 1,
  142.                                     0, 0, 0, 0, 0,
  143.                                     ev.msg, 0L,
  144.                                     &ev.m_x, &ev.m_y, &ev.bstate, &ev.kstate,
  145.                                     &ev.kreturn, &ev.breturn);
  146.     old_mx = ev.m_x;
  147.     old_my = ev.m_y;
  148.  
  149.     if (ev.which != MU_TIMER)
  150.     {
  151.         ev.which &= (~MU_TIMER);
  152.         if (ev.which == MU_M1)
  153.             wake_mouse();
  154.         else
  155.             add_event(&ev);
  156.         return TRUE;
  157.     }
  158.     return FALSE;
  159. }
  160.  
  161. bool check_for_abbruch(void)
  162. {
  163.     EVENT ev;
  164.     int    events;
  165.  
  166.     if (full_event())
  167.         events = MU_KEYBD | MU_TIMER;
  168.     else
  169.     {
  170.         events = MU_KEYBD | MU_BUTTON | MU_MESAG | MU_TIMER;
  171.         if (mouse_sleeps())
  172.             events |= MU_M1;
  173.     }
  174.     ev.which = evnt_multi(events,    0x102, 3, 0,
  175.                                     1, old_mx, old_my, 1, 1,
  176.                                     0, 0, 0, 0, 0,
  177.                                     ev.msg, 0L,
  178.                                     &ev.m_x, &ev.m_y, &ev.bstate, &ev.kstate,
  179.                                     &ev.kreturn, &ev.breturn);
  180.     old_mx = ev.m_x;
  181.     old_my = ev.m_y;
  182.  
  183.     if (ev.which != MU_TIMER)
  184.     {
  185.         ev.which &= (~MU_TIMER);
  186.         if (ev.which == MU_M1)
  187.         {
  188.             wake_mouse();
  189.             return FALSE;
  190.         }
  191.         if (ev.which & MU_KEYBD)                    /* andere Tasten schlucken */
  192.             return (ev.kreturn == 0x011B);
  193.         add_event(&ev);
  194.     }
  195.     return FALSE;
  196. }
  197.  
  198. static void next_action(EVENT *ev)
  199. {
  200.     int    events;
  201.  
  202. again:
  203.     if (get_event(ev))                                    /* Event aus der Schlange */
  204.     {
  205.         old_mx = ev->m_x;
  206.         old_my = ev->m_y;
  207.         if (makro_play)
  208.         {
  209.             if (ev->which != MU_KEYBD)
  210.             {
  211.                 end_play();
  212.                 return;
  213.             }
  214.             else if (ev->kreturn == 0x011B)
  215.             {
  216.                 end_play();
  217.                 goto again;
  218.             }
  219.         }
  220.         else
  221.             return;
  222.     }
  223.     if (from_makro(&ev->kstate, &ev->kreturn))    /* Event vom Makro */
  224.     {
  225.         ev->which = MU_KEYBD;
  226.         return;
  227.     }
  228.                                                                 /* auf Event warten */
  229.     events = MU_KEYBD | MU_BUTTON | MU_MESAG | MU_TIMER;
  230.  
  231.     if (mouse_sleeps())
  232.         events |= MU_M1;
  233.  
  234.     if (winlist_top() == NULL)
  235.         events &= (~MU_TIMER);
  236.  
  237.     ev->which = evnt_multi(events,    0x102, 3, 0,
  238.                                     1, old_mx, old_my, 1, 1,
  239.                                     0, 0, 0, 0, 0,
  240.                                     ev->msg, TIMER_INTERVALL,
  241.                                     &ev->m_x, &ev->m_y, &ev->bstate, &ev->kstate,
  242.                                     &ev->kreturn, &ev->breturn);
  243.     old_mx = ev->m_x;
  244.     old_my = ev->m_y;
  245. }
  246.  
  247. /*****************************************************************************/
  248. /* Ereignis-Verarbeitung                                                                                                         */
  249. /*****************************************************************************/
  250.  
  251. static void handle_keybd(int kstate, int kreturn)
  252. {
  253.     WINDOWP window;
  254.  
  255. #if 0
  256.     if (debug_level)
  257.     {
  258.         TEXTP    t_ptr;
  259.         
  260.         window = winlist_top();
  261.         if (window != NULL)
  262.             t_ptr = get_text(window->handle);
  263.         
  264.         if (kstate == 4 && kreturn == 0x3B00)                /* ^F1 */
  265.         {
  266.             debug("Debug-Special: Ctrl-F1\n");
  267.  
  268.             return;
  269.         }
  270.     }
  271. #endif
  272.  
  273.     to_makro(kstate, kreturn);
  274.     if (!makro_play)
  275.         sleep_mouse();
  276.  
  277.     window = winlist_top();
  278.     if (window == NULL)
  279.         key_global(kstate, kreturn);
  280.     else
  281.     {
  282.         if (!key_window(window, kstate, kreturn))
  283.             key_global(kstate, kreturn);
  284.     }
  285. }
  286.  
  287. /*****************************************************************************/
  288. static void handle_button(int m_x, int m_y, int bstate, int kstate, int breturn)
  289. {
  290.     int        wh;
  291.     WINDOWP    window;
  292.  
  293.     if (!all_iconified)
  294.     {
  295.         wake_mouse();
  296.         wh = wind_find(m_x, m_y);
  297.         window = get_window(wh);
  298.         if (window != NULL)
  299.             click_window(window, m_x, m_y, bstate, kstate, breturn);
  300.     }
  301. }
  302.  
  303. /*****************************************************************************/
  304. static bool str_to_key(char *str, int *kstate, int *kreturn)
  305. {
  306.     char    c, sign, *s1, *s2;
  307.     bool    erg = FALSE;
  308.  
  309.     if (str[0] == EOS)
  310.         return FALSE;
  311.  
  312.     s1 = strrchr(str, '^');
  313.     s2 = strrchr(str, '◆');
  314.     if (s1 > s2)
  315.         str = s1;
  316.     else
  317.         str = s2;
  318.  
  319.     if (str != NULL && strlen(str) >= 2)     /* Sign und Buchstabe */
  320.     {
  321.         sign = *str++;                             /* "Vorzeichen" */
  322.         c      = *str;                                /* Eigentliches Zeichen */
  323.         switch (sign)
  324.         {
  325.             case '^':
  326.                 *kstate = K_CTRL;
  327.                 *kreturn = c;
  328.                 erg = TRUE;
  329.                 break;
  330.  
  331.             case '◆':
  332.                 *kstate = K_ALT;
  333.                 *kreturn = c;
  334.                 erg = TRUE;
  335.                 break;
  336.         }
  337.     }
  338.     return erg;
  339. }
  340.  
  341. void handle_msg(int *msg)
  342. {
  343.     WINDOWP    window;
  344.  
  345.     wake_mouse();
  346.     window= get_window(msg[3]);            /* Zugehöriges Fenster */
  347.  
  348.     switch (msg[0])                            /* Art der Nachricht */
  349.     {
  350.         case MN_SELECTED:
  351.             if (makro_rec)                        /* Makro wird Tastendruck vorgegaukelt */
  352.             {
  353.                 int    kstate, kreturn;
  354.                 char    str[50];
  355.                 
  356.                 get_string(menu, msg[4], str);
  357.                 if (str_to_key(str, &kstate, &kreturn))
  358.                 {
  359.                     kstate |= (kstate & 3);
  360.                     to_makro(kstate, kreturn);
  361.                 }
  362.             }
  363.             handle_menu(msg[3], msg[4], menu_ctrl);
  364.             menu_ctrl = FALSE;
  365.             break;
  366.         case WM_REDRAW  :
  367.             if (msg[3] == akt_handle)
  368.                 redraw_aktion();
  369.             else
  370.                 redraw_window (window, (GRECT*)(msg+4));
  371.             break;
  372.         case WM_CLOSED  :
  373.             do_icon(window->handle, DO_DELETE);
  374.             break;
  375.         case WM_FULLED  :
  376.             full_window (window);
  377.             break;
  378.         case WM_ARROWED :
  379.             arrow_window (window, msg[4], 1);
  380.             break;
  381.         case WM_HSLID     :
  382.             h_slider (window, msg[4]);
  383.             break;
  384.         case WM_VSLID     :
  385.             v_slider (window, msg[4]);
  386.             break;
  387.         case WM_SIZED     :
  388.             size_window (window, (GRECT*)(msg+4), TRUE);
  389.             break;
  390.         case WM_MOVED     :
  391.             move_window (window, (GRECT*)(msg+4));
  392.             break;
  393.         case WM_NEWTOP     : /* Fenster von qed ist irgendwie nach oben gekommen */
  394.         case WM_ONTOP     :
  395.             ontop_window(window);
  396.             break;
  397.         case WM_TOPPED  :
  398.             top_window (window);
  399.             break;
  400.         case WM_UNTOPPED: /* qed hat jetzt nicht mehr das Top-Fenster */
  401.             untop_window (window);
  402.             break;
  403.         case WM_BOTTOMED:     /* AES 4.00 MagiC 3 : Fenster nach hinten */
  404.         case WM_M_BDROPPED :    /* Magic 2 */
  405.             bottom_window (window, msg[0]);
  406.             break;
  407.         case WM_ICONIFY:
  408.             iconify_window(window, (GRECT*)(msg+4));
  409.             break;
  410.         case WM_ALLICONIFY:
  411.             all_iconify(window, (GRECT*)(msg+4));
  412.             break;
  413.         case WM_UNICONIFY:
  414.             if (all_iconified)
  415.                 all_uniconify(NULL, (GRECT*)(msg+4));
  416.             else
  417.                 uniconify_window(window, (GRECT*)(msg+4));
  418.             break;
  419.         case WM_SHADED :
  420.         case WM_UNSHADED :
  421.             shade_window(window, msg[0]);
  422.             break;
  423.  
  424.         case AP_TERM:
  425.             if (all_iconified)
  426.                 all_uniconify(NULL, NULL);
  427.             quick_close = TRUE;
  428.             if (prepare_quit())
  429.                 do_quit();
  430.             break;
  431.         case AP_DRAGDROP :
  432.             if (all_iconified)
  433.                 Bconout(2, 7);
  434.             else
  435.                 handle_dd(msg);
  436.             break;
  437.  
  438.         case SC_CHANGED :
  439.             /*
  440.              * Ignorieren, da wir vor dem Paste sowieso neu laden.
  441.             */
  442.             break;
  443.  
  444.         case VA_START :
  445.         case VA_PROTOSTATUS :
  446.         case VA_DRAG_COMPLETE :
  447.         case VA_DRAGACCWIND :
  448.         case AV_SENDKEY :
  449.             handle_av(msg);
  450.             break;
  451.  
  452.         case SE_INIT:
  453.         case SE_OK:
  454.         case SE_ACK:
  455.         case SE_OPEN:
  456.         case SE_ERROR:
  457.         case SE_ERRFILE:
  458.         case SE_PROJECT:
  459.         case SE_QUIT:
  460.         case SE_TERMINATE:
  461.         case SE_CLOSE :
  462.         case SE_MENU :
  463.             if (all_iconified)
  464.                 all_uniconify(NULL, NULL);
  465.            handle_se(msg);
  466.            break;
  467.  
  468.         case OLGA_INIT :
  469.         case OLE_NEW :
  470.         case OLGA_ACK :
  471.         case OLE_EXIT :
  472.             handle_olga(msg);
  473.             break;
  474.  
  475.         case SH_WDRAW:                /* schickt Freedom ständig */
  476.         case DHST_ACK:                /* SMU antwortet */
  477.             /* ignore */
  478.             break;
  479.  
  480.         case FONT_CHANGED :
  481.             if (msg[4] != 0)
  482.                 font_id = msg[4];
  483.             if (msg[5] != 0)
  484.                 font_pts = msg[5];
  485.             font_change();    
  486.             break;
  487.             
  488.         default:
  489.             if (debug_level)
  490.             {
  491.                 char    str[12];
  492.                 int    d, i, id;
  493.     
  494.                 if ((appl_xgetinfo(4, &d, &d, &i, &d)) && (i == 1))    /* gibts appl_search? */
  495.                 {
  496.                     i = appl_search(0, str, &d, &id);
  497.                     while (i != 0)
  498.                     {
  499.                         if (id == msg[1])
  500.                             break;
  501.                         i = appl_search( 1, str, &d, &id);
  502.                     }
  503.                 }
  504.                 else
  505.                 {
  506.                     strcpy(str, "");
  507.                     id = msg[1];
  508.                 }
  509.                 debug("Unbekannte Msg %d (0x%X) von %s (%d)\n", msg[0], msg[0], str, id);
  510.             }
  511.             break;
  512.     }
  513. }
  514.  
  515. /*****************************************************************************/
  516. void main_loop(void)
  517. {
  518.     EVENT    ev;
  519.     bool    menu_chg;
  520.     long    as_timer = 0, t;
  521.     
  522.     /* Message-Handler für Fenster-Dialoge und -Alerts */
  523.     set_mdial_wincb(handle_msg);
  524.     
  525.     update_menu();
  526.     menu_chg = FALSE;
  527.     onblink_edit();
  528.     do
  529.     {
  530.         quick_close = FALSE;                         /* Sichern der Texte ohne Nachfrage */
  531.         next_action (&ev);
  532. /*
  533.         get_realtop();
  534. */
  535.         if (ev.which == MU_TIMER)                     /* Zeit (nur wenn nichts anderes anliegt) */
  536.         {
  537.             timer_se();
  538.             if (blinking_cursor)
  539.                 blink_edit();
  540.             if (clip_on_disk)
  541.                 save_clip();
  542.  
  543.             if (as_text || as_prj)
  544.             {
  545.                 /*
  546.                  * Weil der do_all_icon() recht viel Rechenzeit verheizt, und
  547.                  * AutoSave min. 1 min wartet, wird er nur jede Minute aufgerufen.
  548.                 */
  549.                 t = Tgettime();
  550.                 if ((t - as_timer) >= 32)
  551.                 {
  552.                     do_all_icon(ALL_TYPES, DO_AUTOSAVE);
  553.                     as_timer = t;
  554.                 }
  555.             }
  556.         }
  557.         if (ev.which & MU_KEYBD)                    /* Taste */
  558.         {
  559.             offblink_edit();
  560.             handle_keybd(ev.kstate, ev.kreturn);
  561.             menu_chg = TRUE;
  562.             onblink_edit();
  563.             while (idle())                             /*    Auch für Makro-Play-Abbruch */
  564.                 ;
  565.         }
  566.         if (ev.which & MU_BUTTON)                    /* Mausknopf */
  567.         {
  568.             offblink_edit();
  569.             handle_button(ev.m_x, ev.m_y, ev.bstate, ev.kstate, ev.breturn);
  570.             menu_chg = TRUE;
  571.             onblink_edit();
  572.         }
  573.         if (ev.which & MU_MESAG)                    /* Meldung */
  574.         {
  575.             if (ev.msg[0] == MN_SELECTED)
  576.                 menu_ctrl = (ev.kstate & K_CTRL);
  577.             offblink_edit();
  578.             handle_msg(ev.msg);
  579.             menu_chg = TRUE;
  580.             onblink_edit();
  581.         }
  582.         if (ev.which & MU_M1)                        /* Maus bewegt */
  583.             wake_mouse();
  584.  
  585.         if (menu_chg && !is_event())                /* Wenn Zeit */
  586.         {
  587.             update_menu();                                /* Eine Aktion kann Menüs verändern */
  588.             menu_chg = FALSE;
  589.         }
  590.         end_undo_seq();
  591.         if (abort_prog)
  592.         {
  593.             int    msg[] = {0,0,0,0,0,0,0,0};
  594.  
  595.             msg[0] = AP_TERM;
  596.             msg[1] = gl_apid;
  597.             appl_write(gl_apid, 16, msg);
  598.         }
  599.     } while (! done);
  600. }
  601.